package com.ycg.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycg.blog.common.R;
import com.ycg.blog.pojo.Category;
import com.ycg.blog.pojo.vo.CategoryVo;
import com.ycg.blog.pojo.vo.SimpleArticleVo;
import com.ycg.blog.service.CategoryService;
import com.ycg.blog.mapper.CategoryMapper;
import org.springframework.stereotype.Service;

import java.util.*;


/**
 * @author lenovo
 * @description 针对表【blog_category(分类信息)】的数据库操作Service实现
 * @createDate 2024-03-02 12:05:04
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {

    @Override
    public R<List<CategoryVo>> getCategoryList() {
        List<CategoryVo> categoryVos = new ArrayList<>();
        List<Category> list = list();
        if (list == null || list.size() == 0) {
            return R.error("数据为空");
        }
        List<Integer> categoryIds = list.stream().mapToInt(Category::getId).boxed().toList();
        // 获取每个分类下所属的文章数量
        Map<String, String> nameAndCount = getArticleIds(categoryIds);

        List<CategoryVo> tops = differTopOrNotTop(list, nameAndCount, true);
        List<CategoryVo> notTops = differTopOrNotTop(list, nameAndCount, false);

        for (CategoryVo top : tops) {
            // 找出top所属的所有分类
            CategoryVo vo = getSubCategories(top, notTops);
            categoryVos.add(vo);
        }

        return R.success(categoryVos);
    }

    /**
     * 区分是否是顶层分类
     *
     * @param list
     * @param nameAndCount
     * @param isTop        1:顶层
     * @return
     */
    private List<CategoryVo> differTopOrNotTop(List<Category> list, Map<String, String> nameAndCount, boolean isTop) {
        return list.stream().filter(item -> isTop ? item.getParentId() == 0 : item.getParentId() > 0)
                .map(item -> {
                    CategoryVo vo = new CategoryVo();
                    vo.setCategory(item);
                    String name = item.getName();
                    vo.setChildren(new ArrayList<>());
                    if (nameAndCount.containsKey(name)) {
                        Integer count = Integer.parseInt(nameAndCount.get(name));
                        vo.setCount(count);
                    }
                    return vo;
                }).toList();
    }

    /**
     * 获取每个分类id下的所有文章id
     *
     * @param categoryIds
     * @return
     */
    private Map<String, String> getArticleIds(List<Integer> categoryIds) {
        Map<String, Map<String, Long>> map = getBaseMapper().getArticleIds(categoryIds);
        HashMap<String, String> nameAndCount = new HashMap<>();
        for (String name : map.keySet()) {
            String count = String.valueOf(map.get(name).get("count"));
            nameAndCount.put(name, count);
        }
        return nameAndCount;
    }

    /**
     * 找出top所属的所有子分类
     *
     * @param current
     * @param notTops
     * @return
     */
    private CategoryVo getSubCategories(CategoryVo current, List<CategoryVo> notTops) {
        // 当前分类有几个次一级分类
        List<CategoryVo> children = notTops.stream().filter(item -> item.getParentId() == current.getId()).toList();
        // 子分类和子分类自查询
        for (int i = 0; i < notTops.size(); i++) {
            ArrayList<CategoryVo> notTopChildren = new ArrayList<>();
            CategoryVo notTop1 = notTops.get(i);
            for (CategoryVo notTop : notTops) {
                if (!Objects.equals(notTop.getId(), notTop1.getId())
                        && Objects.equals(notTop.getParentId(), notTop1.getId())) {
                    notTopChildren.add(notTop);
                }
            }
            notTop1.setChildren(notTopChildren);
        }
        current.setChildren(children);
        return current;
    }


    @Override
    public R<String> updateCategories(Category category) {
        saveOrUpdate(category);
        if (category.getParentId() != null) {
            LambdaUpdateWrapper<Category> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(Category::getId, category.getParentId())
                    .set(Category::getIsEnd, 0);
            update(wrapper);
        }
        return R.success("添加分类成功");
    }

    @Override
    public R<List<SimpleArticleVo>> getSimpleArticlesByCategoryId(Integer categoryId) {
        List<SimpleArticleVo> vos = getBaseMapper().getSimpleArticlesByCategoryId(categoryId);
        return R.success(vos);
    }

    @Override
    public R<String> updateCategoryName(Integer categoryId, String newName) {
        LambdaUpdateWrapper<Category> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Category::getId, categoryId)
                .set(Category::getName, newName);
        update(wrapper);
        return R.success("修改分类名称成功");
    }

    @Override
    public R<String> addCategories(String name, Integer parentId) {
        Category category = new Category();
        category.setName(name);
        if (parentId != null && parentId != 0) {
            category.setParentId(parentId);
        }
        save(category);
        return R.success("新增分类成功");
    }
}




